package com.jt.aop;

import com.jt.annotation.CacheFind;
import com.jt.util.ObjectMapperUtil;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisCluster;
import redis.clients.jedis.JedisSentinelPool;
import redis.clients.jedis.ShardedJedis;

import java.util.Arrays;

@Component //交给spring容器管理
@Aspect //这是一个切面
public class RedisAOP {
    @Autowired
    private JedisCluster jedis;

    /*
    * AOP业务调用
    * 1.拦截指定注解
    * 2.利用环绕通知实现
    * 步骤：
    *   获取key值，从注解中获取key值
    *   检验redis中是否有值
    * 3.知识点补充
    *   指定参数名称进行传值，运行期绑定参数类型完成注解拦截
    *   joinpoint必须位于第一位*/
    @Around("@annotation(cacheFind)")
    public Object around(ProceedingJoinPoint joinPoint, CacheFind cacheFind){


        Object result=null;
        String key=cacheFind.key();
        String args= Arrays.toString(joinPoint.getArgs());
        key=key+"::"+args;

        if (jedis.exists(key)){
            String json=jedis.get(key);
            MethodSignature methodSignature=(MethodSignature) joinPoint.getSignature();
            Class returnType=methodSignature.getReturnType();

            result= ObjectMapperUtil.toObj(json, returnType);
            System.out.println("AOP查询redis缓存");
        }else {
            try {
//                返回方法执行后的结果
                result=joinPoint.proceed();
                String json=ObjectMapperUtil.toJSON(result);
                if (cacheFind.seconds()>0){
                    jedis.setex(key, cacheFind.seconds(), json);

                }else {
                    jedis.set(key, json);
                }
                System.out.println("AOP查询数据库");
            }catch (Throwable e){
                e.printStackTrace();
            }
        }
        return result;
    }
}
